Move DOT stuff into a new helper named DotHelper, adding some specs.

Akinori MUSHA 11 years ago
parent
commit
71f7921fb9

+ 2 - 0
app/controllers/agents_controller.rb

@@ -1,4 +1,6 @@
1 1
 class AgentsController < ApplicationController
2
+  include DotHelper
3
+
2 4
   def index
3 5
     @agents = current_user.agents.page(params[:page])
4 6
 

+ 0 - 39
app/helpers/application_helper.rb

@@ -14,43 +14,4 @@ module ApplicationHelper
14 14
       link_to '<span class="label label-warning">No</span>'.html_safe, agent_path(agent, :tab => (agent.recent_error_logs? ? 'logs' : 'details'))
15 15
     end
16 16
   end
17
-
18
-  def render_agents_diagram(agents)
19
-    if (command = ENV['USE_GRAPHVIZ_DOT']) &&
20
-       (svg = IO.popen([command, *%w[-Tsvg -q1 -o/dev/stdout /dev/stdin]], 'w+') { |dot|
21
-          dot.print agents_dot(agents, true)
22
-          dot.close_write
23
-          dot.read
24
-        } rescue false)
25
-      svg.html_safe
26
-    else
27
-      tag('img', src: URI('https://chart.googleapis.com/chart').tap { |uri|
28
-            uri.query = URI.encode_www_form(cht: 'gv', chl: agents_dot(agents))
29
-          })
30
-    end
31
-  end
32
-
33
-  private
34
-
35
-  def dot_id(string)
36
-    # Backslash escaping seems to work for the backslash itself,
37
-    # despite the DOT language document.
38
-    '"%s"' % string.gsub(/\\/, "\\\\\\\\").gsub(/"/, "\\\\\"")
39
-  end
40
-
41
-  def agents_dot(agents, rich = false)
42
-    "digraph foo {".tap { |dot|
43
-      agents.each.with_index do |agent, index|
44
-        if rich
45
-          dot << '%s[URL=%s];' % [dot_id(agent.name), dot_id(agent_path(agent.id))]
46
-        else
47
-          dot << '%s;' % dot_id(agent.name)
48
-        end
49
-        agent.receivers.each do |receiver|
50
-          dot << "%s->%s;" % [dot_id(agent.name), dot_id(receiver.name)]
51
-        end
52
-      end
53
-      dot << "}"
54
-    }
55
-  end
56 17
 end

+ 40 - 0
app/helpers/dot_helper.rb

@@ -0,0 +1,40 @@
1
+module DotHelper
2
+  def render_agents_diagram(agents)
3
+    if (command = ENV['USE_GRAPHVIZ_DOT']) &&
4
+       (svg = IO.popen([command, *%w[-Tsvg -q1 -o/dev/stdout /dev/stdin]], 'w+') { |dot|
5
+          dot.print agents_dot(agents, true)
6
+          dot.close_write
7
+          dot.read
8
+        } rescue false)
9
+      svg.html_safe
10
+    else
11
+      tag('img', src: URI('https://chart.googleapis.com/chart').tap { |uri|
12
+            uri.query = URI.encode_www_form(cht: 'gv', chl: agents_dot(agents))
13
+          })
14
+    end
15
+  end
16
+
17
+  private
18
+
19
+  def dot_id(string)
20
+    # Backslash escaping seems to work for the backslash itself,
21
+    # despite the DOT language document.
22
+    '"%s"' % string.gsub(/\\/, "\\\\\\\\").gsub(/"/, "\\\\\"")
23
+  end
24
+
25
+  def agents_dot(agents, rich = false)
26
+    "digraph foo {".tap { |dot|
27
+      agents.each.with_index do |agent, index|
28
+        if rich
29
+          dot << '%s[URL=%s];' % [dot_id(agent.name), dot_id(agent_path(agent.id))]
30
+        else
31
+          dot << '%s;' % dot_id(agent.name)
32
+        end
33
+        agent.receivers.each do |receiver|
34
+          dot << "%s->%s;" % [dot_id(agent.name), dot_id(receiver.name)]
35
+        end
36
+      end
37
+      dot << "}"
38
+    }
39
+  end
40
+end

+ 48 - 0
spec/helpers/dot_helper_spec.rb

@@ -0,0 +1,48 @@
1
+require 'spec_helper'
2
+
3
+describe DotHelper do
4
+  describe "#dot_id" do
5
+    it "properly escapes double quotaion and backslash" do
6
+      dot_id('hello\\"').should == '"hello\\\\\\""'
7
+    end
8
+  end
9
+
10
+  describe "with example Agents" do
11
+    class Agents::DotFoo < Agent
12
+      default_schedule "2pm"
13
+
14
+      def check
15
+        create_event :payload => {}
16
+      end
17
+    end
18
+
19
+    class Agents::DotBar < Agent
20
+      cannot_be_scheduled!
21
+
22
+      def check
23
+        create_event :payload => {}
24
+      end
25
+    end
26
+
27
+    before do
28
+      stub(Agents::DotFoo).valid_type?("Agents::DotFoo") { true }
29
+      stub(Agents::DotBar).valid_type?("Agents::DotBar") { true }
30
+    end
31
+
32
+    describe "#agents_dot" do
33
+      it "generates a DOT script" do
34
+        @foo = Agents::DotFoo.new(:name => "foo")
35
+        @foo.user = users(:bob)
36
+        @foo.save!
37
+
38
+        @bar = Agents::DotBar.new(:name => "bar")
39
+        @bar.user = users(:bob)
40
+        @bar.sources << @foo
41
+        @bar.save!
42
+
43
+        agents_dot([@foo, @bar]).should == 'digraph foo {"foo";"foo"->"bar";"bar";}'
44
+        agents_dot([@foo, @bar], true).should == 'digraph foo {"foo"[URL="/agents/%d"];"foo"->"bar";"bar"[URL="/agents/%d"];}' % [@foo.id, @bar.id]
45
+      end
46
+    end
47
+  end
48
+end